package com.hc.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hc.service.IAuthorizationService;
import com.hc.vo.StatusVO;
import com.mysql.cj.core.util.StringUtils;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

public class JWTAuthenticFilter extends FormAuthenticationFilter {

    @Autowired
    IAuthorizationService service;

    @Override
    protected boolean isAccessAllowed(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, Object mappedValue) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        //跨域会先发option
        if (httpRequest.getMethod().equals(HttpMethod.OPTIONS.toString())) {
            return true;
        }
        String token = httpRequest.getHeader(Constant.AUTTH_HEADER_NAME);
        //没有就报废
        if (StringUtils.isNullOrEmpty(token)) {
            writeJson(new StatusVO(Constant.ILLEGAL_TOKEN_CODE), httpRequest, httpResponse);
            return false;
        }
        try {
            //验证token
            IAuthorizationService.TokenStatus result = service.verifyToken(token);
            if (result.equals(IAuthorizationService.TokenStatus.VALID)) {
                return true;
            } else if (result.equals(IAuthorizationService.TokenStatus.INVALID)) {//失败
                writeJson(new StatusVO(Constant.ILLEGAL_TOKEN_CODE), httpRequest, httpResponse);
                return false;
            } else {
                //修改实现，只是告诉前端去调刷新接口即可
                writeJson(new StatusVO(Constant.REFRESH_TOKEN), httpRequest, httpResponse);
                return false;
            }
        } catch (Exception e) {
            writeJson(new StatusVO(Constant.ILLEGAL_TOKEN_CODE), httpRequest, httpResponse);
            return false;
        }
    }

    private void writeJson(StatusVO vo, HttpServletRequest request, HttpServletResponse response) {
        response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,DELETE,PUT,OPTIONS");
        Enumeration enumeration = ((HttpServletRequest) request).getHeaderNames();
        StringBuilder stringBuilder = new StringBuilder();
        while (enumeration.hasMoreElements()) {
            stringBuilder.append(enumeration.nextElement());
        }
        response.addHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, stringBuilder.toString());
        response.setHeader(HttpHeaders.CONTENT_ENCODING, "utf-8");
        response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
        ObjectMapper mapper = new ObjectMapper();
        response.setHeader(HttpHeaders.CONTENT_ENCODING, "utf-8");
        try {
            response.getWriter().write(mapper.writeValueAsString(vo));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        return false;
    }


}
